<?php

namespace rrx\sdk;

class Common
{
    /**
     * 数组转换成uri
     *
     * @param array $data 一维数组
     * @param bool $encode 是否需要url_encode编码
     * @return string uri
     */
    public static function arrToUri(array $data, $encode = true)
    {
        $ds = "&";
        $result = "";
        foreach ($data as $key => $value) {
            if ($key != 'callback' && $value != "" && !is_array($value)) {
                $value = $encode ? urlencode(trim($value)) : trim($value);
                $result = $result . $ds . trim($key) . "=" . $value;
            }
        }

        return ltrim($result, '&');
    }

    /**
     * HTTP以URL的形式发送请求
     *
     * @param string $url 请求地址
     * @param array $data 传递数据
     * @param string $type 请求类型
     * @param boolean $toJson 解析json返回数组
     * @param integer $timeOut 请求超时时间
     * @param array $header 请求头
     * @param string $agent 请求user-agent
     * @return mixed 结果集
     * @throws \Exception
     */
    public static function sendHTTP($url, $data = [], $type = 'GET', $toJson = true, $timeOut = 60, array $header = [], $agent = '')
    {
        $method = strtoupper($type);
        $queryData = is_array($data) ? self::filterEmpty($data) : $data;

        // get请求
        if ($method == 'GET' && is_array($data) && count($data) > 0) {
            $uri = self::arrToUri($data);
            $url = $url . (strpos($url, '?') === false ? '?' : '') . $uri;
            $queryData = [];
        }

        $ch = self::getRequest($url, $queryData, $method, $timeOut, $header, $agent);
        // 发起请求
        $html = curl_exec($ch);
        if ($html === false) {
            throw new \Exception('发起HTTP请求失败!', 0);
        }
        // 关闭请求句柄
        curl_close($ch);
        return ($toJson) ? json_decode($html, true) : $html;
    }

    /**
     * 生成CURL请求
     *
     * @param string $url 请求的URL
     * @param array $data 请求的数据
     * @param string $type 请求方式
     * @param integer $timeOut 超时时间
     * @param array $header 请求头
     * @param string $agent 请求user-agent
     * @return false|resource cURL句柄
     * @throws \Exception
     */
    public static function getRequest($url, $data = [], $type = 'GET', $timeOut = 5, array $header = [], $agent = '')
    {
        // 判断是否为https请求
        $ssl = strtolower(substr($url, 0, 8)) == "https://";
        $ch = curl_init();
        // 设置请求URL
        curl_setopt($ch, CURLOPT_URL, $url);
        // 判断请求类型
        switch (strtoupper($type)) {
            case 'GET':
                curl_setopt($ch, CURLOPT_HTTPGET, true);
                break;
            case 'POST':
                curl_setopt($ch, CURLOPT_POST, true);
                break;
            case 'PUT':
            case 'DELETE':
            case 'PATCH':
                $data = empty($data) ? $data : json_encode($data, JSON_UNESCAPED_UNICODE);
                $header[] = 'Content-Type:application/json';
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
                break;
            default:
                throw new \Exception("不支持的HTTP请求类型({$type})");
        }
        // 判断是否需要传递数据
        if (!empty($data)) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }
        // 设置超时时间
        if ($timeOut > 0) {
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeOut);
        }
        // 设置内容以文本形式返回，而不直接返回
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_VERBOSE, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        // 防止无限重定向
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 6);
        // 设置user-agent
        if ($agent) {
            curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        }
        // 设置请求头
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        if (!empty($header)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        if ($ssl) {
            // 跳过证书检查
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            // 从证书中检查SSL加密算法是否存在
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        return $ch;
    }

    /**
     * 获取毫秒时间戳
     * @return string
     */
    public static function getMicroTime()
    {
        list($msec, $sec) = explode(' ', microtime());
        return sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }

    /**
     * 生成随机字符串
     * @param $length
     * @return string
     */
    public static function randomString($length = 6)
    {
        $str = '';
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol) - 1;
        for ($i = 0; $i < $length; $i++) {
            $str .= $strPol[rand(0, $max)];
        }
        return $str;
    }

    // 过滤数组空值
    private static function filterEmpty($arr)
    {
        foreach ($arr as $key => $value) {
            if (is_array($value)) {
                $arr[$key] = self::filterEmpty($value);
            } else if (empty($value)) {
                unset($arr[$key]);
            }
        }
        return $arr;
    }
}